package com.linkhub.oms.admin.modules.order.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Lists;
import com.linkhub.oms.admin.modules.order.domain.vo.orderpdf.OrderPdfVO;
import com.linkhub.oms.admin.modules.order.domain.vo.orderpdf.OrderProductPdfVO;
import com.linkhub.oms.admin.modules.order.service.OrderInfoAssembleService;
import com.linkhub.oms.common.util.QtOptionalUtil;
import com.linkhub.oms.common.util.QtStreamUtil;
import com.linkhub.oms.dao.mpservice.ILogisticService;
import com.linkhub.oms.dao.mpservice.IOrderProductService;
import com.linkhub.oms.dao.mpservice.IOrderService;
import com.linkhub.oms.dao.mpservice.IShopService;
import com.linkhub.oms.entity.LogisticEntity;
import com.linkhub.oms.entity.OrderEntity;
import com.linkhub.oms.entity.OrderProductEntity;
import com.linkhub.oms.entity.ShopEntity;
import com.linkhub.oms.entity.resulttype.OrderLocalProductResultEntity;
import com.linkhub.oms.entity.resulttype.order.OrderInfoDO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * @Description: OrderInfoAssembleService
 * @Author: echo
 * @Date: 2024/4/1 19:31
 * @Version: 1.0
 */
@Slf4j
@Service
public class OrderInfoAssembleServiceImpl implements OrderInfoAssembleService {

    @Resource
    private IOrderService orderService;
    @Resource
    private IOrderProductService orderProductService;
    @Resource
    private ILogisticService logisticService;
    @Resource
    private IShopService shopService;

    @Override
    public List<OrderInfoDO> assembleOrderInfos(List<OrderEntity> orders) {
        return this.assembleOrderInfos(orders, true);
    }

    @Override
    public List<OrderInfoDO> assembleOrderInfos(List<OrderEntity> orders, boolean deep) {
        if (CollUtil.isEmpty(orders)) {
            return Lists.newArrayListWithCapacity(0);
        }
        List<OrderInfoDO> res = Lists.newArrayListWithCapacity(orders.size());
        if (deep) {
            // deepMapping 商店信息、订单收货地址
            orders = orderService.deepMappingOrders(orders);
        }


        List<String> orderIds = QtStreamUtil.map(orders, OrderEntity::getSysOrderId);
        // 组装订单本地商品
        List<OrderInfoDO> orderWithLocalProducts = orderService.queryOrderWithLocalProducts(orderIds);
        if (CollUtil.isNotEmpty(orderWithLocalProducts)) {
            CollUtil.addAll(res, orderWithLocalProducts);
            orderIds.removeAll(QtStreamUtil.map(orderWithLocalProducts, OrderInfoDO::getSysOrderId));
        }

        // 组装订单商店商品
        List<OrderInfoDO> orderWithShopProducts = orderService.queryOrderWithShopProducts(orderIds);
        if (CollUtil.isNotEmpty(orderWithShopProducts)) {
            CollUtil.addAll(res, orderWithShopProducts);
        }

        // 组装没有商品的订单(拆分订单父订单)
        fillSplitOrders(orders, res);

        // 组装物流信息
        fillOrderChannels(orders);

        // 组装订单主表
        Map<String, OrderEntity> orderMap = QtStreamUtil.toMap(orders, OrderEntity::getSysOrderId);
        QtStreamUtil.peek(res, orderInfo -> orderInfo.setOrder(orderMap.get(orderInfo.getSysOrderId())));

        return res;
    }


    @Override
    public List<OrderInfoDO> assembleOrdersByIds(List<String> sysOrderIds) {
        return this.assembleOrderInfos(orderService.listBySysOrderIds(sysOrderIds));
    }

    @Override
    public OrderInfoDO assembleOrder(String sysOrderIds) {
        List<OrderInfoDO> orders = this.assembleOrdersByIds(Lists.newArrayList(sysOrderIds));
        return QtOptionalUtil.of(orders)
                .map(list -> list.get(0))
                .orElse(OrderInfoDO.emptyOrder());
    }

    @Override
    public List<OrderInfoDO> assembleSubOrders(List<String> orderIds) {
        List<OrderEntity> subOrders = orderService.listSubOrders(orderIds);
        List<String> subOrderIds = QtStreamUtil.map(subOrders, OrderEntity::getSysOrderId);
        List<OrderInfoDO> subOrderInfoDOList = this.assembleOrdersByIds(subOrderIds);
        return subOrderInfoDOList;

    }

    @Override
    public Map<String, List<OrderProductEntity>> queryOrderLocalSkuIds(List<String> orderIds) {
        List<OrderProductEntity> orderProducts = Lists.newArrayList();
        // 查询已转换为本地商品的sku
        List<OrderProductEntity> localProducts = orderProductService.listLocalSkuIds(orderIds);
        CollUtil.addAll(orderProducts, localProducts);
        // 查询已匹配的本地商品sku
        List<OrderLocalProductResultEntity> matchProducts = orderProductService.listOrderLocalProducts(orderIds);
        CollUtil.addAll(orderProducts, QtStreamUtil.map(matchProducts, OrderLocalProductResultEntity::toOrderLocalProduct));

        return QtStreamUtil.group(orderProducts, OrderProductEntity::getSysOrderId);
    }

    @Override
    public OrderPdfVO assembleOrderPdfInfo(OrderInfoDO orderInfoDO) {
        OrderEntity orderEntity = orderInfoDO.getOrder();
        ShopEntity shopEntity = shopService.getByShopId(orderEntity.getSysShopId());

        OrderPdfVO orderPdfVO = new OrderPdfVO();
        orderPdfVO.setSysOrderId(orderEntity.getSysOrderId());
        orderPdfVO.setOrderNumber(orderEntity.getOrderNumber());
        orderPdfVO.setCreatedAt(orderEntity.getCreatedAt());
        orderPdfVO.setShopName(shopEntity.getShopName());
        orderPdfVO.setLogoUrl(StringUtils.defaultIfBlank(shopEntity.getLogoUrl(),""));

        // 本地商品
        List<OrderProductPdfVO> orderProductPdfVOList = QtStreamUtil.map(orderInfoDO.getOrderLocalProducts(),product -> {
            OrderProductPdfVO productPdfVO = new OrderProductPdfVO();
            productPdfVO.setProductEnTitle(product.getProductEnTitle());
            productPdfVO.setCurrentQuantity(product.getCurrentQuantity());
            productPdfVO.setImgUrl(product.getImgUrl());
            return productPdfVO;
        });
        // 平台商品
        CollUtil.addAll(orderProductPdfVOList, QtStreamUtil.map(orderInfoDO.getOrderShopProducts(),product -> {
            OrderProductPdfVO productPdfVO = new OrderProductPdfVO();
            productPdfVO.setProductEnTitle(StringUtils.defaultIfBlank(StringUtils.defaultIfBlank(product.getLocalProductEnTitle(),product.getTitle()),""));
            productPdfVO.setCurrentQuantity(product.getCurrentQuantity());
            productPdfVO.setImgUrl(StringUtils.defaultIfBlank(StringUtils.defaultIfBlank(product.getLocalImgUrl(),product.getImgUrl()),""));
           return productPdfVO;
        }));

        orderPdfVO.setOrderProducts(orderProductPdfVOList);

        return orderPdfVO;
    }

    @Override
    public List<OrderPdfVO> assembleOrderPdfInfos(List<String> sysOrderIds) {
        List<OrderInfoDO> orderInfoDOs = this.assembleOrdersByIds(sysOrderIds);

        return QtStreamUtil.map(orderInfoDOs, this::assembleOrderPdfInfo);
    }

    private void fillSplitOrders(List<OrderEntity> orders, List<OrderInfoDO> res) {
        List<String> hasProductOrderIds = QtStreamUtil.map(res, OrderInfoDO::getSysOrderId);
        for (OrderEntity order : orders) {
            if (!hasProductOrderIds.contains(order.getSysOrderId())) {
                res.add(OrderInfoDO.createDefaultOrder(order.getSysOrderId()));
            }
        }
    }

    private void fillOrderChannels(List<OrderEntity> orders) {
        List<String> channelCodes = QtStreamUtil.filterAndMap(orders,
                order -> StringUtils.isNotBlank(order.getChannelCode()),
                OrderEntity::getChannelCode);
        List<LogisticEntity> channels = logisticService.listByChannelCodes(channelCodes);
        Map<String, LogisticEntity> channelMap = QtStreamUtil.toMap(channels, LogisticEntity::getChannelCode);
        QtStreamUtil.filterAndPeek(orders,
                order -> StringUtils.isNotBlank(order.getChannelCode()),
                order -> QtOptionalUtil.of(channelMap.get(order.getChannelCode()))
                        .map(LogisticEntity::getChannelEName)
                        .ifPresent(order::setChannelEName));

    }
}
